package com.cartoonrabbit.config.wxpay;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.cartoonrabbit.wxapp.properties.WxAppPayProperties;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

@Configuration
public class WeixinPayConfig {

    @Autowired
    private WxAppPayProperties wxAppPayProperties;

    @Bean
    public PrivateKey privateKey(){
        return  getPrivateKey(wxAppPayProperties.getPrivateKeyPath());
    }

    /**
     * 定时从微信平台获取获取微信平台公钥证书，生成验签工具
     * @return
     */
    @Bean
    public Verifier getVerifier() throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();

        //获取商户私钥
        PrivateKey privateKey = getPrivateKey(wxAppPayProperties.getPrivateKeyPath());

        //商户私钥签名对象
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(wxAppPayProperties.getMchSerialNo(),privateKey);

        //身份份认证对象
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(wxAppPayProperties.getMchId(),privateKeySigner);

        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(wxAppPayProperties.getMchId(), wechatPay2Credentials,wxAppPayProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8));
        // ... 若有多个商户号，可继续调用putMerchant添加商户信息

        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(wxAppPayProperties.getMchId());
        return verifier;
    }

    @Bean
    public CloseableHttpClient closeableHttpClient(Verifier verifier){
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(wxAppPayProperties.getMchId(),
                        wxAppPayProperties.getMchSerialNo(),
                        getPrivateKey(wxAppPayProperties.getPrivateKeyPath())
                        )
                .withValidator(new WechatPay2Validator(verifier));
            // ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

            // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
                    CloseableHttpClient httpClient = builder.build();
                    return httpClient;
    }

    /**
     * 商户私钥获取
     * @param filename
     * @return
     */
    private PrivateKey getPrivateKey(String filename){
        PrivateKey merchantPrivateKey = null;
        try {
            InputStream resourceAsStream = this.getClass().getResourceAsStream("/" + filename);
            merchantPrivateKey = PemUtil.loadPrivateKey(
                    resourceAsStream);
        } catch (Exception e) {
            throw new RuntimeException("私钥文件不存在");
        }
        return merchantPrivateKey;
    }
}
